package cn.com.surker.production.controller;

import cn.com.surker.base.BaseEntity;
import cn.com.surker.base.system.dao.SysLineDao;
import cn.com.surker.base.system.entity.SysLine;
import cn.com.surker.common.AESCoder;
import cn.com.surker.common.Code;
import cn.com.surker.common.Constant;
import cn.com.surker.common.HttpRequestHelper;
import cn.com.surker.enums.StateEnum;
import cn.com.surker.enums.production.car.CarWorkStatusEnum;
import cn.com.surker.enums.production.indent.IsProEnum;
import cn.com.surker.enums.production.indent.ProTypeEnum;
import cn.com.surker.enums.production.invoice.*;
import cn.com.surker.handler.BCSStarter;
import cn.com.surker.handler.DisCoordinator;
import cn.com.surker.handler.PrintHandler;
import cn.com.surker.lab.entity.LabExpendUpload;
import cn.com.surker.production.entity.*;
import cn.com.surker.production.entity.vo.InvoiceHandleDetail;
import cn.com.surker.production.entity.vo.ProductionInvoiceVo;
import cn.com.surker.production.service.ErpInvoiceForceService;
import cn.com.surker.spring.RestResultDto;
import cn.com.surker.system.model.CacheUser;
import cn.com.surker.thread.ThreadPools;
import cn.com.surker.util.DateUtil;
import cn.com.surker.util.MathUtils;
import cn.com.surker.util.StringUtils;
import cn.com.surker.workcon.service.ProduceService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.transaction.RollbackException;
import javax.transaction.Status;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * 调度相关页面
 *
 * @author luotao
 * @date 2024/11/7
 */
@Slf4j
@RestController
@RequestMapping("/pro/dispatch")
public class DispatchController extends ProBaseController {
	@Value("${erp.datasource.erp.db}")
	protected String erpDb;
	@Autowired
	private PrintHandler printHandler;
	@Autowired
	private BCSStarter bcsStarter;
	@Autowired
	private DisCoordinator disCoordinator;

	@Autowired
	private ProduceService bcsProduceService;
	@Autowired
	private ErpInvoiceForceService erpInvoiceForceService;

	@Resource
	private SysLineDao sysLineDao;

	/**
	 * 生产派单
	 *
	 * @param lineId       生产线
	 * @param indentId     任务单id
	 * @param invoiceType  发货类型
	 * @param uploadStere  上传方量
	 * @param pumpDeviceId 泵送设备
	 * @param sandAccount  砂浆是否累计
	 * @return
	 */
	@RequestMapping(value = "/do", method = RequestMethod.PUT)
	@ResponseBody
	@Transactional(rollbackFor = RollbackException.class, propagation = Propagation.REQUIRED)
	public RestResultDto dispatch(Long lineId, Long indentId, Long carId, Long driverId, String driver, Integer invoiceType, Double uploadStere, Double sendStere, Long pumpDeviceId, Integer sandAccount,
								  Integer totalCar, Double totalStere) {
		try {
			if (lineId == null) {
				return RestResultDto.fail("请选择生产线");
			}
			if (indentId == null) {
				return RestResultDto.fail("请选择任务单");
			}
			String indentDispathcKey = "INDENT_DISPATCH_WEI_YI_KEY_" + indentId;
			//	加锁,一个任务单10秒钟1次
			boolean acquire = redisUtils.acquireLock(indentDispathcKey, 5);
			if (!acquire) {
				//	没有加锁成功,不执行
				return RestResultDto.fail("上传中,请勿重复操作");
			}
			if (carId == null) {
				return RestResultDto.fail("请选择搅拌车");
			}
			if (uploadStere == null || uploadStere < 0) {
				return RestResultDto.fail("请输入正确的方量");
			}
			if (sendStere == null || sendStere < 0) {
				return RestResultDto.fail("请输入发货方量");
			}
			if (sendStere < uploadStere) {
				return RestResultDto.fail("发货方量不能小于生产方量");
			}
			//	验证生产类型是否正确
			if (!InvoiceSendTypeEnum.CONCRETE.getCode().equals(invoiceType) && !InvoiceSendTypeEnum.SAND.getCode().equals(invoiceType)) {
				return RestResultDto.fail("请选择正确的生产类型");
			}
			//	查询任务单
			ProductionIndent indent = indentService.getById(indentId);
			if (!BaseEntity.validateExist(indent)) {
				return RestResultDto.fail("任务单数据非法");
			}
			//	验证任务单状态
			Integer type = indent.getType();
			if (!ProTypeEnum.WORK.getCode().equals(type)) {
				return RestResultDto.fail("任务单不是正供状态");
			}
			//	验证车辆
			TranCar tranCar = tranCarService.getById(carId);
			if (tranCar == null) {
				return RestResultDto.fail("请选择运输车辆");
			}
			//	验证车辆状态
			// Integer carStatus = tranCar.getCarStatus();
			//	验证车辆的装载方量
			Double maxStere = tranCar.getMaxStere();
			if (uploadStere > maxStere) {
				return RestResultDto.fail("派单方量大于了车辆的最大运输方量(" + maxStere + "方)");
			}
			ProductionIndentPump indentPump = indentPumpService.queryDefaultIndentId(erpDb, indentId);
			if (indentPump == null) {
				return RestResultDto.fail("任务单没有设置浇筑方式或泵送设备");
			}
			/*if (driverId == null) {
				return RestResultDto.fail("请选择司机");
			}*/
			//	验证泵送方式
			/*Long castModeId = indent.getCastModeId();
			CastMode castMode = castModeService.getById(castModeId);
			Integer needDevice = castMode.getCost();
			if (PumpCostEnum.COST.getCode().equals(needDevice)) {
				//	需要派遣泵送设备,验证设备
				if (pumpDeviceId == null) {
					return RestResultDto.fail("请选择泵送设备");
				}
				//	查询任务单的泵送设备
				List<PumpDevice> pumpDeviceList = pumpDeviceService.findByIndentId(orgId, indentId);
				if (pumpDeviceList == null || pumpDeviceList.isEmpty()) {
					return RestResultDto.fail("任务单没有选择泵送设备");
				}
				boolean coPumpDev = false;
				for (PumpDevice pumpDevice : pumpDeviceList) {
					Long id = pumpDevice.getId();
					if (pumpDeviceId.equals(id)) {
						coPumpDev = true;
						break;
					}
				}
				if (!coPumpDev) {
					// 泵送设备非法
					return RestResultDto.fail("上传的泵送设备不在任务单中");
				}
			} else {
				pumpDeviceId = null;
			}*/
			//	根据任务单,生产线,查询上传记录
			List<LabExpendUpload> labExpendUploads = labUploadService.queryByIndentId(erpDb, orgId, indentId, lineId);
			if (labExpendUploads == null) {
				return RestResultDto.fail("未查询到上传配合比");
			}
			//	配合比信息
			LabExpendUpload labExpendUpload = labExpendUploads.get(0);
			//	配合比编号
			String recipe = labExpendUpload.getCode();
			String morRec = recipe;
			//	上传记录id
			Long labExpendUploadId = labExpendUpload.getId();
			Date nowDate = new Date();
			//	车牌号
			String carCode = tranCarService.queryCarCode(orgId, carId, DateUtil.convertString(nowDate));
			CacheUser loginUser = getUser();
			String loginName = loginUser.getName();
			//	创建派单code
			// String dispatchCode = ProductionIndentDispatch.initCode(orgCode);
			/*Integer totalCar = 1;
			Double totalStere = uploadStere;
			//	查询该任务单的总车次和总方量
			List<ProductionInvoice> existInvoiceList = invoiceService.findByIndent(erpDb, indentId);
			if (existInvoiceList != null && existInvoiceList.size() > 0){
				for (int i = 0,s = existInvoiceList.size();i < s;i++){
					ProductionInvoice invoice = existInvoiceList.get(i);
					Double oldSendStere = invoice.getSendStere();
					if (oldSendStere != null && oldSendStere > 0) {
						totalCar++;
						totalStere = MathUtils.add(totalStere, oldSendStere);
					}
				}
			}*/
			Integer loadType = indent.getRoadType();
			Integer overLimit = indent.getOverLimit();
			//	创建发货单
			ProductionInvoice invoice = new ProductionInvoice();
			invoice.setOrgId(indent.getOrgId());
			// invoice.setCode(ProductionInvoice.initCode(orgCode));
			invoice.initCode(orgCode);
			// invoice.setDispatchCode(dispatchCode);
			invoice.setIndentId(indentId);
			invoice.setInvoiceType(invoiceType);
			invoice.setCreateType(InvoiceCreateTypeEnum.AUTOMATIC.getCode());
			//	泵送设备是发货单自己的数据
			invoice.setDistance(indent.getDistance());
			invoice.setCarId(carId);
			invoice.setDriverId(driverId);
			invoice.setDriver(driver);
			invoice.setMixId(lineId);
			invoice.setDispatcher(loginUser.getId());
			invoice.setDispatcherName(loginName);
			invoice.setRoadType(loadType);
			invoice.setOverLimit(overLimit);
			invoice.setProcess(InvoiceProcessEnum.QUERN_RECEIVE.getCode());
			invoice.setSendStere(sendStere);
			//	默认累计
			invoice.setIsAdd(0);
			//	创建时间
			invoice.setCreateTime(nowDate);
			invoice.setCreator(loginName);
			invoice.setStatus(StateEnum.ENABLED.getCode());
			invoice.setTotalCar(totalCar);
			invoice.setTotalStere(totalStere);
			invoice.setLinkPumpId(indentPump.getId());
			// 保存发货单数据
			invoiceService.save(invoice);
			//	发货单id
			Long invoiceId = invoice.getId();
			//	保存发货单数据
			ProductionIndentDispatch indentDispatch = new ProductionIndentDispatch();
			indentDispatch.setInvoiceId(invoiceId);
			indentDispatch.setOrgId(orgId);
			//indentDispatch.setCode(dispatchCode);
			indentDispatch.initCode(orgCode);
			indentDispatch.setIndentId(indentId);
			indentDispatch.setLineId(lineId);
			indentDispatch.setLabExpendId(labExpendUploadId);
			indentDispatch.setUploadType(invoiceType);
			indentDispatch.setUploadStere(uploadStere);
			indentDispatch.setUploadTime(nowDate);
			indentDispatch.setSandAccount(sandAccount);
			indentDispatch.setPumpDeviceId(pumpDeviceId);
			indentDispatch.setCarId(carId);
			indentDispatch.setDriver(driver);
			indentDispatch.setStatus(StateEnum.ENABLED.getCode());
			indentDispatch.setCreator(loginName);
			indentDispatch.setCreateTime(nowDate);
			indentDispatch.setProStatus(InvoiceProcessEnum.QUERN_RECEIVE.getCode());
			indentDispatch.setTotalCar(totalCar);
			indentDispatch.setTotalStere(totalStere);
			boolean save = indentDispatchService.save(indentDispatch);
			Long dispatchId = indentDispatch.getId();
			//	修改车辆状态为等待接料
			tranCarService.updateStatus(orgId, carId, CarWorkStatusEnum.PRO.getCode(), false, null);
			//	判断该任务单是否有实际开盘时间
			Date actualStartTime = indent.getActualStartTime();
			if (actualStartTime == null) {
				//	设置实际开盘时间并更新数据
				indent.setActualStartTime(new Date());
				indent.setIsPro(IsProEnum.WORK.getCode());
				indentService.updateById(indent);
			}
			//	上传到工控机
			int i;
			long time1 = 0, time2 = 0;
			try {
				//	设置
				indentDispatch.setIndentCode(indent.getCode());
				indentDispatch.setRecipe(recipe);
				indentDispatch.setCarCode(carCode);
				time1 = System.currentTimeMillis();
				i = bcsProduceService.insert(lineId, indentDispatch);
				time2 = System.currentTimeMillis();
				long hs = time2 - time1;
				log.info("工控派单耗时:" + hs);
			} catch (Exception e) {
				time2 = System.currentTimeMillis();
				long hs = time2 - time1;
				log.info("工控异常派单耗时:" + hs);
				log.error("往工控派单异常:", e);
				TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
				bcsProduceService.rollbackLine(lineId);
				return RestResultDto.fail("往工控派单失败");
			}
			if (i < 1) {
				//	工控机插入失败,回滚事误
				TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
				bcsProduceService.rollbackLine(lineId);
				return RestResultDto.fail("往工控派单失败2");
			}
			//	提交erp事务
			TransactionAspectSupport.currentTransactionStatus().isCompleted();
			//	提交工控事务
			bcsProduceService.commitTranLine(lineId);
			//	写入缓存
			redisUtils.rightPush(BCSStarter.REDIS_BCS_DISPATCH_KEY, dispatchId.toString());
			//	启动查询派单信息操作
			ThreadPoolExecutor commonThreadPool = ThreadPools.getCommonThreadPool();
			commonThreadPool.execute(new Runnable() {
				@Override
				public void run() {
					//	确保是新事务
					// System.err.println("执行查询");
					bcsStarter.startDispatch(dispatchId);
				}
			});
			//	派车
			commonThreadPool.execute(new Runnable() {
				@Override
				public void run() {
					SysLine sysLine = sysLineDao.selectById(lineId);
					String lineName = "";
					if (sysLine != null) {
						lineName = "";
					}
					//	开启派车
					String postUrl = "https://weight.chixugroup.com/driver/center-v1/send-line";
					Map<String, Object> param = new HashMap<>();
					param.put("orgId", orgId);
					param.put("code", carCode);
					param.put("line", lineName);
					param.put("carNo", tranCar.getCarNo());
					String token = AESCoder.encrypt(lineName + "_" + orgId + "_" + carCode, Constant.centerSecret);
					param.put("token", token);
					String result = HttpRequestHelper.post(postUrl, param);

				}
			});
			memoryCache.remove(DisCoordinator.lingProducingKey);
		} catch (Exception e) {
			log.error("===派单失败===", e);
			//	会滚事务
			bcsProduceService.rollbackLine(lineId);
			TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
			return RestResultDto.fail("系统异常,操作失败");
		}
		//	写入成功后,用定时任务查询工控机的生产数据
		return RestResultDto.success();
	}

	/**
	 * 补料信息
	 *
	 * @param invoiceId 发货单
	 * @param disId     旧的派单信息
	 * @param stere     补料方量
	 * @return
	 */
	@RequestMapping(value = "/add/stere", method = RequestMethod.PUT)
	@ResponseBody
	@Transactional(rollbackFor = RollbackException.class, propagation = Propagation.REQUIRED)
	public RestResultDto addDispatch(Long invoiceId, Long disId, Double stere) {
		Date nowDate = new Date();
		try {
			if (invoiceId == null || disId == null) {
				return RestResultDto.fail("请选择发货单原本的派单信息");
			}
			if (stere == null || stere < 0) {
				return RestResultDto.fail("请输入生产方量");
			}
			//	查询之前的补料信息
			ProductionInvoice invoice = invoiceService.getById(invoiceId);
			if (!BaseEntity.validateExist(invoice)) {
				return RestResultDto.fail("未查询到发货单信息");
			}
			//	查询生产线
			ProductionIndentDispatch oldDis = indentDispatchService.getById(disId);
			if (oldDis == null) {
				return RestResultDto.fail("未查询到旧派单数据");
			}
			//	计算累计方量
			Double accuStere = invoiceService.queryTranStere(invoiceId);
			//	查询该车辆的最大运输方量
			Long carId = invoice.getCarId();
			TranCar tranCar = tranCarService.getById(carId);
			Double maxStere = tranCar.getMaxStere();
			if (accuStere > maxStere) {
				return RestResultDto.fail("该车辆已累计装载" + accuStere + "方,本此派单" + stere + "方后,超出车辆最大运输方量(" + maxStere + "方)");
			}
			//	查询合同车辆
			TranConCar tranConCar = tranConCarService.queryLink(orgId, carId, DateUtil.convertString(nowDate));
			if (tranConCar == null) {
				return RestResultDto.fail("未查询到车辆关联合同");
			}
			//	车辆自编号
			String carCode = tranConCar.getCode();
			Long lineId = oldDis.getLineId();
			Long indentId = invoice.getIndentId();
			//	查询任务单信息
			ProductionIndent indent = indentService.getById(indentId);
			//	根据任务单,生产线,查询上传记录
			List<LabExpendUpload> labExpendUploads = labUploadService.queryByIndentId(erpDb,orgId, indentId, lineId);
			if (labExpendUploads == null) {
				return RestResultDto.fail("未查询到上传配合比");
			}
			//	配合比信息
			LabExpendUpload labExpendUpload = labExpendUploads.get(0);
			//	配合比编号
			String recipe = labExpendUpload.getCode();
			//	上传记录id
			Long labExpendUploadId = labExpendUpload.getId();
			//	登录人员信息
			CacheUser user = getUser();
			String userName = user.getName();

			//	派单编码
			// String dispatchCode = ProductionIndentDispatch.initCode(orgCode);
			//	进行派单
			ProductionIndentDispatch indentDispatch = new ProductionIndentDispatch();
			indentDispatch.setInvoiceId(invoiceId);
			indentDispatch.setOrgId(orgId);
			// indentDispatch.setCode(dispatchCode);
			indentDispatch.initCode(orgCode);
			indentDispatch.setIndentCode(indent.getCode());
			indentDispatch.setIndentId(indentId);
			indentDispatch.setRecipe(recipe);
			indentDispatch.setLineId(lineId);
			indentDispatch.setLabExpendId(labExpendUploadId);
			indentDispatch.setUploadType(invoice.getInvoiceType());
			indentDispatch.setUploadStere(stere);
			indentDispatch.setUploadTime(nowDate);
			// indentDispatch.setSandAccount();
			// indentDispatch.setPumpDeviceId();
			indentDispatch.setCarId(invoice.getCarId());
			indentDispatch.setCarCode(carCode);
			indentDispatch.setDriver(invoice.getDriver());
			indentDispatch.setStatus(StateEnum.ENABLED.getCode());
			indentDispatch.setCreator(userName);
			indentDispatch.setCreateTime(nowDate);
			indentDispatch.setProStatus(InvoiceProcessEnum.QUERN_RECEIVE.getCode());
			//	保存数据
			indentDispatchService.save(indentDispatch);
			Long dispatchId = indentDispatch.getId();
			//	上传到工控机
			int i;
			try {
				indentDispatch.setIndentCode(indent.getCode());
				//	上传工控机
				i = bcsProduceService.insert(lineId, indentDispatch);
			} catch (Exception e) {
				e.printStackTrace();
				TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
				bcsProduceService.rollbackLine(lineId);
				return RestResultDto.fail("往工控派单失败");
			}
			if (i < 1) {
				//	工控机插入失败,回滚事误
				TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
				bcsProduceService.rollbackLine(lineId);
				return RestResultDto.fail("往工控派单失败");
			}
			//	提交erp事务
			TransactionAspectSupport.currentTransactionStatus().isCompleted();
			//	提交事务
			bcsProduceService.commitTranLine(lineId);
			//	写入缓存
			redisUtils.rightPush(BCSStarter.REDIS_BCS_DISPATCH_KEY, dispatchId.toString());
			//	启动查询派单信息操作
			ThreadPoolExecutor commonThreadPool = ThreadPools.getCommonThreadPool();
			commonThreadPool.execute(new Runnable() {
				@Override
				public void run() {
					//	确保是新事务
					bcsStarter.startDispatch(dispatchId);
				}
			});
		} catch (Exception e) {
			log.error("===补料信息===", e);
			//	会滚事务
			bcsProduceService.rollbackAll();
			TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
			return RestResultDto.fail("系统异常,操作失败");
		}
		return RestResultDto.success();
	}

	/**
	 * 换车操作
	 *
	 * @param invoiceId
	 * @param carId
	 * @param driver
	 * @return
	 */
	@RequestMapping(value = "/replace/car", method = RequestMethod.PUT)
	@ResponseBody
	@Transactional(rollbackFor = RollbackException.class, propagation = Propagation.REQUIRED)
	public RestResultDto replaceCar(Long invoiceId, Long carId, Long driverId, String driver) {
		if (invoiceId == null) {
			return RestResultDto.fail("请选择发货单");
		}
		if (carId == null) {
			return RestResultDto.fail("请选择车辆");
		}
		if (StringUtils.isBlank(driver)) {
			return RestResultDto.fail("请选择司机");
		}
		//	验证车辆
		TranCar tranCar = tranCarService.getById(carId);
		if (!BaseEntity.validateExist(tranCar)) {
			// 车辆不存在
			return RestResultDto.fail("车辆不存在");
		}
		//	查询该发货单数据
		ProductionInvoice invoice = invoiceService.getById(invoiceId);
		if (!BaseEntity.validateExist(invoice)) {
			return RestResultDto.fail("发货单不存在");
		}
		//	更新车辆信息
		Integer carStatus = null;
		Integer process = invoice.getProcess();
		if (InvoiceProcessEnum.QUERN_PRO.getCode().equals(process)) {
			carStatus = CarWorkStatusEnum.PRO.getCode();
		} else {
			// 不需要换车
			return RestResultDto.fail("该发货单不为等待生产状态,不需要换车");
		}
		//	计算累计方量
		Double accuStere = invoiceService.queryTranStere(invoiceId);
		//	查询该车辆的最大运输方量
		Double maxStere = tranCar.getMaxStere();
		if (accuStere > maxStere) {
			return RestResultDto.fail("该发货的的装载方量为(" + accuStere + ")方,新派遣的车辆的最大运输量为(" + maxStere + ")方,不允许操作");
		}
		//	旧的车辆
		@NotNull(message = "请选择运输车辆") Long oldCarId = invoice.getCarId();
		//	新车辆
		String newCarNo = tranCar.getCarNo();
		//	备注
		String remarks = "更换车辆,旧车辆(" + oldCarId + ");新车辆(" + carId + ")";
		//	修改发货单车辆
		invoice.setCarId(carId);
		invoice.setDriverId(driverId);
		invoice.setDriver(driver);
		invoice.addRemark(remarks);
		//	更新发货单
		invoiceService.updateById(invoice);
		//	更新派单数据
		UpdateWrapper<ProductionIndentDispatch> uw = new UpdateWrapper<>();
		uw.eq("invoice_id", invoiceId);
		uw.eq("status", StateEnum.ENABLED.getCode());
		uw.set("car_id", carId);
		uw.set("driver", driver);
		indentDispatchService.update(uw);
		//	更新新车辆车辆信息
		tranCar.setCarStatus(carStatus);
		tranCarService.updateById(tranCar);
		//	更新旧车辆信息为休息
		tranCarService.updateStatus(orgId, oldCarId, CarWorkStatusEnum.REST.getCode(), false, null);
		// 更新工控机车辆信息
		// bcsStarter.startDispatch();

		return RestResultDto.success();
	}

	/**
	 * 20250109 	换线功能废弃
	 *
	 * @param invoiceId 发货单
	 * @param lineId    生产线
	 * @return
	 */
	public RestResultDto replaceLine(Long invoiceId, Long lineId) {
		if (invoiceId == null) {
			return RestResultDto.fail("请选择发货单");
		}
		if (lineId == null) {
			return RestResultDto.fail("请选择生产线");
		}
		//	查询发货单
		ProductionInvoice invoice = invoiceService.getById(invoiceId);
		if (!BaseEntity.validateExist(invoice)) {
			return RestResultDto.fail("发货单不存在");
		}
		Integer process = invoice.getProcess();
		if (!InvoiceProcessEnum.QUERN_PRO.getCode().equals(process)) {
			return RestResultDto.fail("发货单不是待生产状态,不允许操作");
		}
		// 查询发货单下的派单
		List<ProductionIndentDispatch> dispatches = indentDispatchService.queryByInvoice(invoiceId);
		for (int i = 0, s = dispatches.size(); i < s; i++) {
			//	删除派单
			ProductionIndentDispatch dispatch = dispatches.get(0);
			Long dispatchId = dispatch.getId();
			bcsStarter.startDelDis(dispatchId);
		}


		return RestResultDto.success();
	}

	/**
	 * 添加发货单的派单信息
	 *
	 * @return
	 */
	@RequestMapping(value = "/add/inv", method = RequestMethod.PUT)
	@ResponseBody
	@Transactional(rollbackFor = RollbackException.class, propagation = Propagation.REQUIRED)
	public RestResultDto addInvDispatch(Long invoiceId, Long lineId, Double stere) {
		if (invoiceId == null) {
			return RestResultDto.fail("请选择发货单");
		}
		if (lineId == null) {
			return RestResultDto.fail("请选择生产线");
		}
		if (stere == null || stere < 0) {
			return RestResultDto.fail("请输入正确的方量");
		}
		//	查询发货单
		ProductionInvoice invoice = invoiceService.getById(invoiceId);
		if (!BaseEntity.validateExist(invoice)) {
			return RestResultDto.fail("发货单不存在或者已经删除");
		}
		//	验证发货单状态
		Integer process = invoice.getProcess();
		if (!InvoiceProcessEnum.PRO_COMPLETE.getCode().equals(process)) {
			return RestResultDto.fail("仅生产完成且未出站的车辆可以补料");
		}
		//	查询任务单
		@NotNull(message = "请选择任务单") Long indentId = invoice.getIndentId();
		ProductionIndent indent = indentService.getById(indentId);
		if (!BaseEntity.validateExist(indent)) {
			return RestResultDto.fail("任务单数据非法");
		}
		//	验证任务单状态
		Integer type = indent.getType();
		if (!ProTypeEnum.WORK.getCode().equals(type)) {
			return RestResultDto.fail("任务单不是正供状态");
		}
		List<LabExpendUpload> labExpendUploads = labUploadService.queryByIndentId(erpDb,orgId, indentId, lineId);
		if (labExpendUploads == null) {
			return RestResultDto.fail("未查询到上传配合比");
		}
		// 验证是否允许生产数据
		Long conId = indent.getConId();
		Long strengthId = indent.getStrengthId();
		RestResultDto conValRes = validateConPro(conId, strengthId, stere);
		if (RestResultDto.SUCCESS != conValRes.getCode()) {
			//	验证失败
			return conValRes;
		}
		//	配合比信息
		LabExpendUpload labExpendUpload = labExpendUploads.get(0);
		//	配合比编号
		String recipe = labExpendUpload.getCode();
		//	上传记录id
		Long labExpendUploadId = labExpendUpload.getId();
		CacheUser loginUser = getUser();
		String loginName = loginUser.getName();
		Date nowDate = new Date();
		//	创建派单code
		// String dispatchCode = ProductionIndentDispatch.initCode(orgCode);
		Integer totalCar = 1;
		Double totalStere = stere;
		//	查询该任务单的总车次和总方量
		List<ProductionInvoice> existInvoiceList = invoiceService.findByIndent(erpDb, indentId);
		if (existInvoiceList != null && existInvoiceList.size() > 0) {
			for (int i = 0, s = existInvoiceList.size(); i < s; i++) {
				ProductionInvoice oldInvoice = existInvoiceList.get(i);
				Double proStere = oldInvoice.getSendStere();
				if (proStere != null && proStere > 0) {
					totalCar++;
					totalStere = MathUtils.add(totalStere, proStere);
				}
			}
		}
		@NotNull(message = "请选择运输车辆") Long carId = invoice.getCarId();
		TranCar tranCar = tranCarService.getById(carId);
		//	计算累计方量
		Double accuStere = invoiceService.queryTranStere(invoiceId);
		//	查询该车辆的最大运输方量
		Double maxStere = tranCar.getMaxStere();
		if (accuStere > maxStere) {
			return RestResultDto.fail("该车辆已累计装载" + accuStere + "方,本此派单" + stere + "方后,超出车辆最大运输方量(" + maxStere + "方)");
		}
		//	查询合同车辆
		TranConCar tranConCar = tranConCarService.queryLink(orgId, carId, DateUtil.convertString(nowDate));
		if (tranConCar == null) {
			return RestResultDto.fail("未查询到车辆关联合同");
		}
		//	车辆自编号
		String carCode = tranConCar.getCode();
		//	保存派单数据
		@NotNull(message = "请选择发货类型") Integer invoiceType = invoice.getInvoiceType();
		@NotBlank(message = "请选择司机") String driver = invoice.getDriver();
		//	车牌号
		ProductionIndentDispatch indentDispatch = new ProductionIndentDispatch();
		indentDispatch.setInvoiceId(invoiceId);
		indentDispatch.setOrgId(orgId);
		// indentDispatch.setCode(dispatchCode);
		indentDispatch.initCode(orgCode);
		indentDispatch.setIndentId(indentId);
		indentDispatch.setLineId(lineId);
		indentDispatch.setLabExpendId(labExpendUploadId);
		indentDispatch.setUploadType(invoiceType);
		indentDispatch.setUploadStere(stere);
		indentDispatch.setUploadTime(nowDate);
		// indentDispatch.setSandAccount(sandAccount);
		// indentDispatch.setPumpDeviceId(pumpDeviceId);
		indentDispatch.setCarId(carId);
		indentDispatch.setCarCode(carCode);
		indentDispatch.setDriver(driver);
		indentDispatch.setStatus(StateEnum.ENABLED.getCode());
		indentDispatch.setCreator(loginName);
		indentDispatch.setCreateTime(nowDate);
		indentDispatch.setProStatus(InvoiceProcessEnum.QUERN_RECEIVE.getCode());
		indentDispatch.setTotalCar(totalCar);
		indentDispatch.setTotalStere(totalStere);
		boolean save = indentDispatchService.save(indentDispatch);
		Long dispatchId = indentDispatch.getId();
		//	修改车辆状态为等待接料
		tranCarService.updateStatus(orgId, carId, CarWorkStatusEnum.PRO.getCode(), false, null);
		//	上传到工控机
		int i;
		try {
			//	设置参数
			indentDispatch.setIndentCode(indent.getCode());
			indentDispatch.setRecipe(recipe);
			indentDispatch.setCarCode(carCode);
			i = bcsProduceService.insert(lineId, indentDispatch);
		} catch (Exception e) {
			log.error("往工控派单失败", e);
			TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
			bcsProduceService.rollbackLine(lineId);
			return RestResultDto.fail("往工控派单失败");
		}
		if (i < 1) {
			//	工控机插入失败,回滚事误
			TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
			bcsProduceService.rollbackLine(lineId);
			return RestResultDto.fail("往工控派单失败");
		}
		try {
			//	提交erp事务
			TransactionAspectSupport.currentTransactionStatus().isCompleted();
			//	提交事务
			bcsProduceService.commitTranLine(lineId);
			//	写入缓存
			redisUtils.rightPush(BCSStarter.REDIS_BCS_DISPATCH_KEY, dispatchId.toString());
			//	启动查询派单信息操作
			ThreadPoolExecutor commonThreadPool = ThreadPools.getCommonThreadPool();
			commonThreadPool.execute(new Runnable() {
				@Override
				public void run() {
					//	确保是新事务
					// System.err.println("执行查询");
					bcsStarter.startDispatch(dispatchId);
				}
			});
		} catch (Exception e) {
			log.error("===补料信息1===", e);
			bcsProduceService.rollbackLine(lineId);
			//	会滚事务
			TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
			return RestResultDto.fail("系统异常,操作失败");
		}
		return RestResultDto.success();
	}

	/**
	 * 查询生产线下面的车辆
	 *
	 * @return
	 */
	@RequestMapping(value = "/line/producing", method = RequestMethod.POST)
	@ResponseBody
	public RestResultDto lineProducing() {
		Object o = null;
		try {
			o = memoryCache.get(DisCoordinator.lingProducingKey);
		} catch (Exception e) {
			e.printStackTrace();
		}
		if (o == null) {
			//	没有查询出信息,直接从数据库查询
			o = disCoordinator.lingProducing();
		}
		return RestResultDto.success(o);
	}

	/**
	 * 删除派单
	 *
	 * @param
	 * @return
	 */
	@RequestMapping(value = "/del/{dispatchId}", method = RequestMethod.DELETE)
	@ResponseBody
	@Transactional(rollbackFor = RollbackException.class, propagation = Propagation.REQUIRED)
	public RestResultDto delDispatch(@PathVariable Long dispatchId) {
		RestResultDto restResultDto = bcsStarter.startDelDis(dispatchId);
		return restResultDto;
	}

	/**
	 * 弹窗数据
	 * 查询最近10分钟的
	 * @return
	 */
	@RequestMapping(value = "/pup-up", method = RequestMethod.POST)
	@ResponseBody
	public RestResultDto pupUpInvoice() {
		Date nowDate = new Date();
		Date date = DateUtil.convertBeforeMinDate(nowDate, 10);
		QueryWrapper<ProductionInvoice> qw = new QueryWrapper<>();
		qw.ge("pro_time", date);
		qw.eq("status", StateEnum.ENABLED.getCode());
		qw.eq("pop_up", PopEnum.REQUIRED.getCode());
		qw.last("limit 1");
		qw.orderByDesc("pro_time");
		ProductionInvoice invoice = invoiceService.getOne(qw);
		if (invoice != null) {
			Long invoiceId = invoice.getId();
			ProductionInvoiceVo productionInvoiceVo = invoiceService.queryDetail(erpDb, orgId, invoiceId);
			ThreadPoolExecutor commonThreadPool = ThreadPools.getCommonThreadPool();
			commonThreadPool.execute(new Runnable() {
				@Override
				public void run() {
					//	设置为已经弹单了
					/*UpdateWrapper<ProductionInvoice> uw = new UpdateWrapper<>();
					uw.eq("id", invoiceId);
					uw.set("pop_up", PopEnum.NOT_REQUIRED.getCode());*/
					// boolean update = invoiceService.update(new ProductionInvoice(), uw);
					invoice.setPopUp(PopEnum.NOT_REQUIRED.getCode());
					invoiceService.updateById(invoice);
				}
			});
			return RestResultDto.success(productionInvoiceVo);
		}
		return RestResultDto.fail();
	}

	/**
	 * 取消发货单的弹单
	 *
	 * @param invId
	 * @return
	 */
	@RequestMapping(value = "/cancel/pop", method = RequestMethod.GET)
	@ResponseBody
	public RestResultDto cancelPopInv(Long invId) {
		if (invId == null) {
			return RestResultDto.fail("请选择发货单");
		}
		UpdateWrapper<ProductionInvoice> qw = new UpdateWrapper<>();
		qw.eq("id", invId);
		qw.set("pop_up", PopEnum.NOT_REQUIRED.getCode());
		boolean update = invoiceService.update(null, qw);
		return RestResultDto.success();
	}

	/**
	 * 打印数据
	 *
	 * @param invoiceId
	 * @return
	 */
	@RequestMapping(value = "/print/{invoiceId}", method = RequestMethod.POST)
	@ResponseBody
	public RestResultDto printInvoice(@PathVariable Long invoiceId) {
		printHandler.addInvoice(PrintHandler.disPrintKey, invoiceId);
		return RestResultDto.success("请等待打印");
	}

	/**
	 * 退砼单的处理,表示退砼单重新派车
	 *
	 * @param invBakId    退砼单的派车
	 * @param indentId    任务单
	 * @param lineId      生产线
	 * @param uploadStere 派单方量
	 * @return
	 */
	@RequestMapping(value = "/inv/bak", method = RequestMethod.PUT)
	@ResponseBody
	@Transactional(rollbackFor = RollbackException.class, propagation = Propagation.REQUIRED)
	public RestResultDto invBackDispatch(Long invBakId, Long indentId, Long lineId, Double uploadStere, Double sendStere, String remark, Integer totalCar, Double totalStere) {
		if (invBakId == null || indentId == null || lineId == null || uploadStere == null || sendStere == null) {
			return RestResultDto.fail(Code.PARAM_EMPTY.getMsg());
		}
		Date nowDate = new Date();
		InvoiceHandle invback = invoiceHandleService.getById(invBakId);
		if (!BaseEntity.validateExist(invback)) {
			return RestResultDto.fail("没有查询到退砼单");
		}
		//	判断是否是退砼
		if (!ShipTypeEnum.BACK_SCRAP_WEIGHT.getCode().equals(invback.getOperateType())) {
			return RestResultDto.fail("不是退砼类型,不能处理");
		}
		//	查询该退砼单下是否有处理记录
		List<InvoiceHandleDetail> handleDetails = invoiceHandleService.findByPId(invBakId);
		if (handleDetails != null && handleDetails.size() > 0) {
			return RestResultDto.fail("该退砼单下有其他操作记录");
		}
		//	目标发货单
		Long sourceInvoiceId = invback.getSourceInvoiceId();
		ProductionInvoice sourceInvoice = invoiceService.getById(sourceInvoiceId);
		if (!BaseEntity.validateExist(sourceInvoice)) {
			return RestResultDto.fail("该退砼单关联的发货单异常");
		}
		//	验证任务单
		ProductionIndent newIndent = indentService.getById(indentId);
		if (!BaseEntity.validateExist(newIndent)) {
			return RestResultDto.fail("任务单数据非法");
		}
		//	验证任务单状态
		Integer type = newIndent.getType();
		if (!ProTypeEnum.WORK.getCode().equals(type)) {
			return RestResultDto.fail("任务单不是正供状态");
		}
		Long conId = newIndent.getConId();
		//	新任务单的标号
		Long newLevelId = newIndent.getStrengthId();
		RestResultDto conValRes = validateConPro(conId, newLevelId, uploadStere);
		if (RestResultDto.SUCCESS != conValRes.getCode()) {
			//	验证失败
			return conValRes;
		}
		List<LabExpendUpload> labExpendUploads = labUploadService.queryByIndentId(erpDb,orgId, indentId, lineId);
		if (labExpendUploads == null) {
			return RestResultDto.fail("未查询到上传配合比");
		}
		//	退砼方量加派单方量不能大于车辆的装载方量
		@NotNull(message = "请选择运输车辆") Long carId = sourceInvoice.getCarId();
		TranCar tranCar = tranCarService.getById(carId);
		Double maxStere = tranCar.getMaxStere();
		Double bakStere = invback.getWeightStere();
		if (MathUtils.add(bakStere, uploadStere) > maxStere) {
			return RestResultDto.fail("当前退砼(" + bakStere + ")方,派单(" + uploadStere + ")方,大于了车辆的装载方量(" + maxStere + ")方");
		}
		//	查询合同车辆
		TranConCar tranConCar = tranConCarService.queryLink(orgId, carId, DateUtil.convertString(nowDate));
		if (tranConCar == null) {
			return RestResultDto.fail("未查询到车辆关联合同");
		}
		//	旧任务单的标号
		Long oldIndentId = sourceInvoice.getIndentId();
		//	旧的任务单
		ProductionIndent oldIndent = indentService.getById(oldIndentId);
		if (oldIndent == null) {
			return RestResultDto.fail("原任务单不存在");
		}
		Long oldLevelId = oldIndent.getStrengthId();
		boolean strengthLower = strengthLower(oldLevelId, newLevelId);
		if (!strengthLower) {
			return RestResultDto.fail("整车转料标号只允许降级处理");
		}
		ProductionIndentPump indentPump = indentPumpService.queryDefaultIndentId(erpDb, indentId);
		if (indentPump == null) {
			return RestResultDto.fail("任务单没有设置浇筑方式或泵送设备");
		}
		//	车辆自编号
		String carCode = tranConCar.getCode();
		//	配合比信息
		LabExpendUpload labExpendUpload = labExpendUploads.get(0);
		//	配合比编号
		String recipe = labExpendUpload.getCode();
		//	上传记录id
		Long labExpendUploadId = labExpendUpload.getId();
		CacheUser loginUser = getUser();
		String loginName = loginUser.getName();
		//	创建派单code
		// String dispatchCode = ProductionIndentDispatch.initCode(orgCode);
		/*Integer totalCar = 1;
		Double totalStere = sendStere;
		//	查询该任务单的总车次和总方量
		Map<String, Object> totalMap = invoiceService.queryTotalStere(erpDb, indentId);
		if (totalMap != null) {
			Object totalCarObj = totalMap.get("totalCar");
			Object totalStereObj = totalMap.get("totalStere");
			if (totalCarObj != null && totalCarObj instanceof Number) {
				totalCar += Integer.valueOf(totalCarObj.toString());
			}
			if (totalStereObj != null && totalStereObj instanceof Number) {
				totalStere = MathUtils.add(totalStere, Double.valueOf(totalStereObj.toString()));
			}
		}*/
		//	保存派单数据
		@NotNull(message = "请选择发货类型") Integer invoiceType = sourceInvoice.getInvoiceType();
		@NotBlank(message = "请选择司机") String driver = sourceInvoice.getDriver();
		//	==========创建发货单==========
		ProductionInvoice invoice = new ProductionInvoice();
		invoice.setOrgId(newIndent.getOrgId());
		// invoice.setCode(ProductionInvoice.initCode(orgCode));
		invoice.initCode(orgCode);
		// invoice.setDispatchCode(dispatchCode);
		invoice.setIndentId(indentId);
		invoice.setInvoiceType(invoiceType);
		invoice.setCreateType(InvoiceCreateTypeEnum.AUTOMATIC.getCode());
		//	泵送设备是发货单自己的数据
		// invoice.setPumpDevice(pumpDeviceId);
		invoice.setDistance(newIndent.getDistance());
		invoice.setCarId(carId);
		invoice.setDriver(driver);
		invoice.setMixId(lineId);
		invoice.setDispatcher(loginUser.getId());
		invoice.setDispatcherName(loginName);
		invoice.setRoadType(newIndent.getRoadType());
		invoice.setProcess(InvoiceProcessEnum.QUERN_RECEIVE.getCode());
		invoice.setSendStere(sendStere);
		//	创建时间
		invoice.setCreateTime(nowDate);
		invoice.setCreator(loginName);
		invoice.setStatus(StateEnum.ENABLED.getCode());
		invoice.setTotalCar(totalCar);
		invoice.setTotalStere(totalStere);
		invoice.setLinkPumpId(indentPump.getId());
		// 保存发货单数据
		invoiceService.save(invoice);
		//	==========创建派单==========
		//	发货单id
		Long invoiceId = invoice.getId();
		ProductionIndentDispatch indentDispatch = new ProductionIndentDispatch();
		indentDispatch.setInvoiceId(invoiceId);
		indentDispatch.setOrgId(orgId);
		// indentDispatch.setCode(dispatchCode);
		indentDispatch.initCode(orgCode);
		indentDispatch.setIndentId(indentId);
		indentDispatch.setLineId(lineId);
		indentDispatch.setLabExpendId(labExpendUploadId);
		indentDispatch.setUploadType(invoiceType);
		indentDispatch.setUploadStere(uploadStere);
		indentDispatch.setUploadTime(nowDate);
		// indentDispatch.setSandAccount(sandAccount);
		// indentDispatch.setPumpDeviceId(pumpDeviceId);
		indentDispatch.setCarId(carId);
		indentDispatch.setDriver(driver);
		indentDispatch.setStatus(StateEnum.ENABLED.getCode());
		indentDispatch.setCreator(loginName);
		indentDispatch.setCreateTime(nowDate);
		indentDispatch.setProStatus(InvoiceProcessEnum.QUERN_RECEIVE.getCode());
		indentDispatch.setTotalCar(totalCar);
		indentDispatch.setTotalStere(totalStere);
		indentDispatch.setUploadType(invoiceType);
		indentDispatch.setRemark(remark);
		boolean save = indentDispatchService.save(indentDispatch);
		Long dispatchId = indentDispatch.getId();
		//	修改车辆状态为等待接料
		tranCarService.updateStatus(orgId, carId, CarWorkStatusEnum.PRO.getCode(), false, null);
		//	==========创建一条转出信息记录==========
		//	退砼方量
		// Double backStere = invback.getOperateStere();
		Double backStere = invback.getWeightStere();
		InvoiceHandle tranRecord = new InvoiceHandle();
		tranRecord.setSourceOrgId(orgId);
		tranRecord.setSourceInvoiceId(invback.getSourceInvoiceId());
		tranRecord.setTargetOrgId(orgId);
		tranRecord.setTargetInvoiceId(invoiceId);
		tranRecord.setTranType(TranTypeEnum.BATCH_TRAN.getCode());
		tranRecord.setOperateType(ShipTypeEnum.INVOICE_TRAN_TO_OWN.getCode());
		tranRecord.setOperateStere(backStere);
		// tranRecord.setExpectStere(backStere);
		tranRecord.setPid(invBakId);
		tranRecord.setCreator(loginName);
		tranRecord.setCreateTime(nowDate);
		tranRecord.setStatus(StateEnum.ENABLED.getCode());
		tranRecord.setRemark("退砼补料发货创建");
		//	保存转料记录
		invoiceHandleService.save(tranRecord);
		//	上传到工控机
		int i;
		try {
			//	设置参数
			indentDispatch.setIndentCode(newIndent.getCode());
			indentDispatch.setRecipe(recipe);
			indentDispatch.setCarCode(carCode);
			i = bcsProduceService.insert(lineId, indentDispatch);
		} catch (Exception e) {
			e.printStackTrace();
			TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
			bcsProduceService.rollbackLine(lineId);
			return RestResultDto.fail("往工控派单失败");
		}
		if (i < 1) {
			//	工控机插入失败,回滚事误
			TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
			bcsProduceService.rollbackLine(lineId);
			return RestResultDto.fail("往工控派单失败");
		}
		try {
			//	提交erp事务
			TransactionAspectSupport.currentTransactionStatus().isCompleted();
			//	提交事务
			bcsProduceService.commitTranLine(lineId);
			//	写入缓存
			redisUtils.rightPush(BCSStarter.REDIS_BCS_DISPATCH_KEY, dispatchId.toString());
			//	启动查询派单信息操作
			ThreadPoolExecutor commonThreadPool = ThreadPools.getCommonThreadPool();
			commonThreadPool.execute(new Runnable() {
				@Override
				public void run() {
					//	确保是新事务
					// System.err.println("执行查询");
					bcsStarter.startDispatch(dispatchId);
				}
			});
		} catch (Exception e) {
			log.error("===补料信息2===", e);
			//	会滚事务
			TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
			bcsProduceService.rollbackLine(lineId);
			return RestResultDto.fail("系统异常,操作失败");
		}

		return RestResultDto.success();
	}

	/**
	 * 生产中断
	 *
	 * @param disId  派单id
	 * @param remark 生产派单
	 * @return
	 */
	@RequestMapping(value = "/prod/error", method = RequestMethod.PUT)
	@ResponseBody
	@Transactional(rollbackFor = RollbackException.class, propagation = Propagation.REQUIRED)
	public RestResultDto prodError(Long disId, String remark) {
		if (true) {
			return RestResultDto.fail("暂未开放");
		}
		if (disId == null) {
			return RestResultDto.fail("请选择派单");
		}
		if (StringUtils.isBlank(remark)) {
			return RestResultDto.fail("请输入中断原因");
		}
		//	查询派单
		ProductionIndentDispatch indentDispatch = indentDispatchService.getById(disId);
		if (!BaseEntity.validateExist(indentDispatch)) {
			return RestResultDto.fail("该派单不存在或者已经被删除");
		}
		//	判断该派单是否正在生产中
		Integer proStatus = indentDispatch.getProStatus();
		if (!InvoiceProcessEnum.PRO.getCode().equals(proStatus)) {
			return RestResultDto.fail("该派单未开始生产或者生产已经完成");
		}
		//	保存数据,
		indentDispatch.setProStatus(InvoiceProcessEnum.WORK_ORDER_1.getCode());
		indentDispatchService.updateById(indentDispatch);
		//	更新发货单数据
		Long invoiceId = indentDispatch.getInvoiceId();
		ProductionInvoice productionInvoice = invoiceService.getById(invoiceId);
		productionInvoice.setProcess(InvoiceProcessEnum.WORK_ORDER_1.getCode());
		invoiceService.updateById(productionInvoice);
		//	更改派单状态
		BCSStarter.proDispatchCache.remove(disId);
		return RestResultDto.success();
	}

	/**
	 * 查询派单状态
	 *
	 * @return
	 */
	@RequestMapping(value = "/error/msg", method = RequestMethod.GET)
	@ResponseBody
	public RestResultDto queryDisStatus() {
		//	查询缓存种的消息数据
		Object o = redisUtils.leftPop(BCSStarter.REDIS_BCS_DISPATCH_ERROR_MSG_KEY);
		if (o != null) {
			//	有消息才返回成功
			return RestResultDto.success(o);
		} else {
			return RestResultDto.fail();
		}
	}

	/**
	 * 手动刷新消耗
	 *
	 * @param disId
	 * @return
	 */
	@RequestMapping(value = "/refresh/lab", method = RequestMethod.GET)
	@ResponseBody
	public RestResultDto refreshLab(Long disId) {
		if (disId == null) {
			return RestResultDto.fail("请选择派单信息");
		}
		bcsStarter.startInvoice(disId);
		return RestResultDto.success("操作成功,请等待");
	}

	/**
	 * 查询消耗数据
	 *
	 * @return
	 */
	@RequestMapping(value = "/refresh/data", method = RequestMethod.GET)
	@ResponseBody
	public RestResultDto refreshDatas() {
		//	正在生产
		//	查询车辆
		//	生产完成车辆
		//	运输车辆
		//	调度页面发货单
		//  退回操作
		//	加载任务单方量
		//	加载近10车
		return RestResultDto.success();
	}

	/**
	 * 强制完成生产发货单,将发货单的发货信息全部置为完成状态,并新增强制完成记录
	 *
	 * @return
	 */
	@RequestMapping(value = "/force/comp", method = RequestMethod.PUT)
	@ResponseBody
	@Transactional(rollbackFor = RollbackException.class, propagation = Propagation.REQUIRED)
	public RestResultDto forceComp(Long disId, String remark) {
		if (disId == null) {
			return RestResultDto.fail("请选择派单id");
		}
		if (StringUtils.isBlank(remark)) {
			return RestResultDto.fail("请输入原因");
		}
		CacheUser user = getUser();
		ProductionIndentDispatch indentDispatch = indentDispatchService.getById(disId);
		if (indentDispatch == null) {
			return RestResultDto.fail("未查询出派单数据");
		}
		Long invoiceId = indentDispatch.getInvoiceId();
		//	查询发货单
		ProductionInvoice invoice = invoiceService.getById(invoiceId);
		if (invoice == null) {
			return RestResultDto.fail("未查询出发货数据");
		}
		Date nowDate = new Date();
		//	完成派单
		indentDispatch.setProStatus(InvoiceProcessEnum.PRO_COMPLETE.getCode());
		indentDispatchService.updateById(indentDispatch);
		//	完成发货单
		Date proTime = invoice.getProTime();
		if (proTime == null) {
			invoice.setProTime(nowDate);
		}
		//	设置发货单状态
		invoice.setProcess(InvoiceProcessEnum.PRO_COMPLETE.getCode());
		//	准备弹单
		invoice.setPopUp(PopEnum.REQUIRED.getCode());
		//	更新数据
		invoiceService.updateById(invoice);
		//	修改车辆
		tranCarService.updateStatus(orgId, invoice.getCarId(), CarWorkStatusEnum.PRO_COMPLETE.getCode(), false, null);
		//	开始过磅
		ThreadPoolExecutor commonThreadPool = ThreadPools.getCommonThreadPool();
		commonThreadPool.execute(new Runnable() {
			@Override
			public void run() {
				//	查询发货单数据
				ProductionInvoiceVo invoiceVo = invoiceService.queryOverview(erpDb, orgId, invoiceId);
				erpWeightOrderService.beginWeight(orgId, orgName, dsId, invoiceVo, "砼生产(强制完成)过磅");
			}
		});
		//	创建强制完成数据
		Long orgId = invoice.getOrgId();
		Long mixId = invoice.getMixId();
		InvoiceForce invoiceForce = new InvoiceForce(orgId, mixId, invoiceId, disId, StateEnum.ENABLED.getCode(), user.getName(), nowDate, remark);
		erpInvoiceForceService.save(invoiceForce);
		//	清除派单进程
		BCSStarter.proDispatchCache.remove(disId);
		return RestResultDto.success();
	}
}
